<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>教师管理系统 - Vue版</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: #f5f7fa;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            color: #333;
        }

        .navbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: linear-gradient(135deg, #2c3e50, #1a2530);
            color: white;
            padding: 12px 25px;
            position: relative;
            z-index: 100;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        }

        .logo-container {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .logo-container img {
            height: 40px;
            filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
        }

        .logo-container h1 {
            font-size: 1.6rem;
            font-weight: 600;
            color: white;
        }

        .user-info-container {
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .user-avatar {
            width: 45px;
            height: 45px;
            border-radius: 50%;
            background: #3498db;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.3rem;
            font-weight: bold;
            color: white;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .user-avatar:hover {
            transform: scale(1.05);
            background: #2980b9;
        }

        .dropdown-menu {
            position: absolute;
            top: 60px;
            right: 0;
            background: white;
            border-radius: 8px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
            width: 200px;
            overflow: hidden;
            z-index: 1000;
            display: none;
        }

        .dropdown-menu.show {
            display: block;
        }

        .dropdown-header {
            padding: 12px;
            background: #f8f9fa;
            border-bottom: 1px solid #eee;
        }

        .dropdown-header h4 {
            font-size: 1rem;
            color: #2c3e50;
            margin-bottom: 5px;
        }

        .dropdown-header p {
            font-size: 0.85rem;
            color: #777;
        }

        .dropdown-item {
            padding: 10px 15px;
            display: flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            transition: all 0.2s ease;
            color: #555;
            font-size: 0.95rem;
        }

        .dropdown-item:hover {
            background: #f0f7ff;
            color: #3498db;
        }

        .dropdown-item i {
            width: 20px;
            text-align: center;
            font-size: 0.9rem;
        }

        .dropdown-divider {
            height: 1px;
            background: #eee;
            margin: 5px 0;
        }

        .logout-btn {
            background: rgba(255, 255, 255, 0.15);
            color: white;
            border: 1px solid rgba(255, 255, 255, 0.3);
            padding: 7px 15px;
            border-radius: 20px;
            cursor: pointer;
            font-weight: 500;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 0.95rem;
        }

        .logout-btn:hover {
            background: rgba(255, 255, 255, 0.25);
            transform: translateY(-2px);
        }

        .container {
            display: flex;
            flex: 1;
            padding: 15px;
            max-width: 1600px;
            margin: 0 auto;
            width: 100%;
            gap: 15px;
        }

        .sidebar {
            width: 220px;
            background: white;
            border-radius: 12px;
            padding: 15px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
            height: fit-content;
        }

        .sidebar-header {
            padding: 12px 10px;
            border-bottom: 1px solid #eaeaea;
            margin-bottom: 15px;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .sidebar-header i {
            font-size: 1.2rem;
            color: #3498db;
        }

        .sidebar-header h2 {
            color: #2c3e50;
            font-size: 1.2rem;
            font-weight: 600;
        }

        .sidebar ul {
            list-style: none;
            padding: 0;
        }

        .sidebar ul li {
            margin: 8px 0;
        }

        .sidebar ul li a {
            text-decoration: none;
            color: #555;
            display: flex;
            align-items: center;
            gap: 12px;
            padding: 12px 15px;
            border-radius: 8px;
            transition: all 0.3s ease;
            font-size: 1rem;
            font-weight: 500;
        }

        .sidebar ul li a:hover {
            background: #f0f7ff;
            color: #3498db;
        }

        .sidebar ul li a.active {
            background: #e1f0ff;
            color: #2980b9;
            font-weight: 600;
        }

        .sidebar ul li a i {
            font-size: 1.1rem;
            width: 22px;
            text-align: center;
        }

        .main-content {
            flex: 1;
            background: white;
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
            display: flex;
            flex-direction: column;
            gap: 20px;
        }

        .welcome-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
            padding-bottom: 15px;
            border-bottom: 1px solid #eaeaea;
        }

        .welcome-header h2 {
            color: #2c3e50;
            font-size: 1.5rem;
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .welcome-header h2 i {
            color: #3498db;
            background: #e1f0ff;
            width: 45px;
            height: 45px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.3rem;
        }

        .class-selector {
            display: flex;
            align-items: center;
            gap: 12px;
            background: #f0f7ff;
            padding: 12px 15px;
            border-radius: 8px;
            width: fit-content;
        }

        .class-selector label {
            font-weight: 500;
            color: #2980b9;
            font-size: 0.95rem;
        }

        .class-selector select {
            padding: 8px 15px;
            border: 1px solid #cce5ff;
            border-radius: 6px;
            background: white;
            font-size: 0.95rem;
            color: #2c3e50;
            width: 180px;
            appearance: none;
            background-repeat: no-repeat;
            background-position: calc(100% - 12px) center;
            background-size: 12px;
            padding-right: 35px;
        }

        .section {
            background: white;
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 3px 8px rgba(0, 0, 0, 0.03);
            border: 1px solid #eaeaea;
        }

        .section-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .section-header h3 {
            color: #2c3e50;
            font-size: 1.3rem;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .action-btn {
            background: #3498db;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 20px;
            cursor: pointer;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 6px;
            transition: all 0.3s ease;
            font-size: 0.95rem;
        }

        .action-btn:hover {
            background: #2980b9;
            transform: translateY(-2px);
        }

        .class-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
            gap: 15px;
            margin-top: 15px;
        }

        .class-card {
            background: white;
            border-radius: 10px;
            padding: 15px;
            box-shadow: 0 3px 8px rgba(0, 0, 0, 0.03);
            border: 1px solid #eaeaea;
            transition: all 0.3s ease;
            display: flex;
            flex-direction: column;
        }

        .class-card:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.08);
            border-color: #cce5ff;
        }

        .class-card-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .class-card h4 {
            color: #2c3e50;
            font-size: 1.2rem;
            margin-bottom: 8px;
        }

        .class-card p {
            color: #555;
            margin: 4px 0;
            font-size: 0.9rem;
        }

        .class-stats {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 10px;
            margin: 15px 0;
        }

        .stat-card {
            background: #f8fafd;
            border-radius: 8px;
            padding: 10px;
            text-align: center;
        }

        .stat-card .stat-value {
            font-size: 1.2rem;
            font-weight: bold;
            color: #3498db;
        }

        .stat-card .stat-label {
            font-size: 0.8rem;
            color: #777;
        }

        .class-actions {
            display: flex;
            gap: 10px;
            margin-top: 15px;
        }

        .class-actions button {
            flex: 1;
            background: #e1f0ff;
            color: #2980b9;
            border: none;
            padding: 10px;
            border-radius: 8px;
            cursor: pointer;
            font-weight: 500;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 5px;
            transition: all 0.3s ease;
            font-size: 0.9rem;
        }

        .class-actions button:hover {
            background: #3498db;
            color: white;
        }

        .class-card button {
            flex: 1;
            background: #e1f0ff;
            color: #2980b9;
            border: none;
            padding: 7px 12px;
            border-radius: 18px;
            cursor: pointer;
            font-weight: 500;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 5px;
            transition: all 0.3s ease;
            font-size: 0.9rem;
        }

        .class-card button:hover {
            background: #3498db;
            color: white;
        }

        .roster-textarea {
            width: 100%;
            min-height: 150px;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 8px;
            font-family: monospace;
            margin-bottom: 15px;
        }

        .roster-preview {
            margin-top: 20px;
            max-height: 300px;
            overflow-y: auto;
        }

        .student-row {
            display: flex;
            justify-content: space-between;
            padding: 10px;
            border-bottom: 1px solid #eee;
        }

        .student-row:nth-child(even) {
            background-color: #f9f9f9;
        }

        .student-info {
            flex: 1;
        }

        .student-actions {
            display: flex;
            gap: 5px;
        }

        .remove-student {
            color: #e74c3c;
            cursor: pointer;
        }

        .add-student-form {
            display: flex;
            gap: 10px;
            margin-top: 15px;
            padding: 10px;
            background: #f5f7fa;
            border-radius: 8px;
        }

        .add-student-form input {
            flex: 1;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }

        .error-message {
            color: #e74c3c;
            margin: 5px 0;
        }

        .hint-text {
            font-size: 0.9rem;
            color: #777;
            margin-bottom: 10px;
        }

        .student-management-modal {
            max-height: 80vh;
            overflow-y: auto;
        }

        .import-actions {
            display: flex;
            justify-content: space-between;
            margin-top: 20px;
            padding-top: 15px;
            border-top: 1px solid #eee;
        }

        .data-table {
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 3px 6px rgba(0, 0, 0, 0.03);
            background: white;
            border: 1px solid #eaeaea;
            margin-top: 12px;
            font-size: 0.95rem;
        }

        .data-table th {
            background: #3498db;
            color: white;
            padding: 14px 12px;
            text-align: center;
            font-weight: 500;
            font-size: 0.95rem;
        }

        .data-table th:first-child {
            border-top-left-radius: 8px;
        }

        .data-table th:last-child {
            border-top-right-radius: 8px;
        }

        .data-table td {
            padding: 12px;
            border-bottom: 1px solid #f0f7ff;
            color: #555;
            text-align: center;
        }

        .data-table tr:last-child td {
            border-bottom: none;
        }

        .data-table tr:nth-child(even) {
            background-color: #f9fcff;
        }

        .data-table tr:hover {
            background-color: #f0f7ff;
        }

        .data-table .status-badge {
            padding: 4px 10px;
            border-radius: 18px;
            font-size: 0.8rem;
            font-weight: 500;
        }

        /* 操作按钮横向排列 */
        .action-buttons {
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        }

        .status-pending {
            background-color: #fff8e6;
            color: #f39c12;
        }

        .status-submitted {
            background-color: #e6f7e9;
            color: #27ae60;
        }

        .data-table button {
            background: #e1f0ff;
            color: #2980b9;
            border: none;
            padding: 7px 12px;
            border-radius: 18px;
            cursor: pointer;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 5px;
            transition: all 0.3s ease;
            font-size: 0.9rem;
        }

        .data-table button:hover {
            background: #3498db;
            color: white;
        }

        .grade-badge {
            display: inline-block;
            padding: 4px 10px;
            border-radius: 18px;
            font-weight: 600;
            background: #e1f0ff;
            color: #2980b9;
            font-size: 0.9rem;
        }

        /* 添加标签页样式 */
        .tab-nav {
            display: flex;
            border-bottom: 1px solid #eee;
            margin-bottom: 20px;
        }

        .tab-nav button {
            padding: 10px 20px;
            background: none;
            border: none;
            cursor: pointer;
            position: relative;
            font-weight: 500;
            color: #555;
        }

        .tab-nav button.active {
            color: #3498db;
            font-weight: 600;
        }

        .tab-nav button.active::after {
            content: '';
            position: absolute;
            bottom: -1px;
            left: 0;
            right: 0;
            height: 3px;
            background: #3498db;
        }

        /* 添加实验面板 */
        .add-experiment-panel {
            margin-top: 20px;
            padding: 15px;
            background: #f9f9f9;
            border-radius: 8px;
        }

        /* 添加成绩输入框样式 */
        .grade-input {
            width: 60px;
            padding: 5px;
            border: 1px solid #ddd;
            border-radius: 4px;
            text-align: center;
        }

        /* 调整表格单元格内的输入框 */
        .data-table td input {
            margin: 0 auto;
            display: block;
        }

        /* 表单行样式 */
        .form-row {
            display: flex;
            gap: 15px;
            margin-bottom: 15px;
        }

        .form-row .form-group {
            flex: 1;
        }

        .progress-bar {
            height: 5px;
            background: #e0edf8;
            border-radius: 3px;
            overflow: hidden;
            margin-top: 4px;
        }

        .progress {
            height: 100%;
            background: #3498db;
            border-radius: 3px;
        }

        /* 资源卡片样式 */
        .resource-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 15px;
            margin-top: 15px;
        }

        .resource-card {
            display: flex;
            align-items: center;
            padding: 15px;
            border: 1px solid #eaeaea;
            border-radius: 8px;
            background: #f9f9f9;
            transition: all 0.3s ease;
        }

        .resource-card:hover {
            background: #f0f7ff;
            transform: translateY(-3px);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }

        .resource-icon {
            width: 50px;
            height: 50px;
            background: #e1f0ff;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 15px;
            font-size: 1.5rem;
            color: #3498db;
        }

        .resource-info {
            flex: 1;
        }

        .resource-info strong {
            display: block;
            margin-bottom: 5px;
            color: #2c3e50;
        }

        .resource-info p {
            margin: 3px 0;
            font-size: 0.9rem;
            color: #555;
        }

        .public-badge {
            display: inline-block;
            padding: 2px 8px;
            background: #e6f7e9;
            color: #27ae60;
            border-radius: 10px;
            font-size: 0.8rem;
        }

        .private-badge {
            display: inline-block;
            padding: 2px 8px;
            background: #ffebee;
            color: #e53935;
            border-radius: 10px;
            font-size: 0.8rem;
        }

        .resource-info a {
            display: inline-block;
            margin-top: 8px;
            color: #3498db;
            text-decoration: none;
            font-weight: 500;
        }

        .resource-info a:hover {
            text-decoration: underline;
        }

        /* 模态框样式 */
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.5);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
        }

        .modal-content {
            background: white;
            border-radius: 10px;
            width: 80%;
            max-width: 800px;
            max-height: 90vh;
            overflow-y: auto;
            padding: 20px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
        }

        /* 增大模态框尺寸 */
        .wide-modal {
            max-width: 1000px;
        }

        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 1px solid #eee;
        }

        .modal-header h3 {
            font-size: 1.5rem;
            color: #2c3e50;
        }

        .close-btn {
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
            color: #777;
            transition: all 0.3s ease;
        }

        .close-btn:hover {
            color: #e53935;
            transform: rotate(90deg);
        }

        .modal-section {
            margin-bottom: 25px;
        }

        .modal-section h4 {
            font-size: 1.2rem;
            margin-bottom: 15px;
            color: #2c3e50;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .modal-section ul {
            padding-left: 20px;
        }

        .modal-section li {
            margin-bottom: 8px;
            line-height: 1.5;
        }

        .modal-footer {
            display: flex;
            justify-content: flex-end;
            gap: 10px;
            padding-top: 20px;
            border-top: 1px solid #eee;
        }

        .btn {
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            font-weight: 500;
            transition: all 0.3s ease;
        }

        .btn-secondary {
            background: #f5f7fa;
            color: #555;
            border: 1px solid #ddd;
        }

        .btn-secondary:hover {
            background: #eaeaea;
        }

        .btn-primary {
            background: #3498db;
            color: white;
            border: 1px solid #2980b9;
        }

        .btn-primary:hover {
            background: #2980b9;
        }

        .no-data {
            text-align: center;
            padding: 20px;
            color: #777;
            font-style: italic;
        }

        /* Vue加载状态样式 */
        .loading-container {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 180px;
        }

        .loading-spinner {
            width: 40px;
            height: 40px;
            border: 4px solid rgba(52, 152, 219, 0.3);
            border-radius: 50%;
            border-top-color: #3498db;
            animation: spin 1s ease-in-out infinite;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        .dashboard-content {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 20px;
            margin-top: 15px;
        }

        .dashboard-card {
            background: #f0f7ff;
            border-radius: 10px;
            padding: 20px;
            text-align: center;
            transition: transform 0.3s ease;
        }

        .dashboard-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        }

        .dashboard-card i {
            font-size: 2.5rem;
            color: #3498db;
            margin-bottom: 15px;
        }

        .dashboard-card h4 {
            color: #2c3e50;
            margin-bottom: 10px;
        }

        .dashboard-card p {
            font-size: 1.8rem;
            font-weight: bold;
            color: #3498db;
        }

        .settings-content {
            max-width: 600px;
        }

        .setting-item {
            margin-bottom: 25px;
            padding-bottom: 20px;
            border-bottom: 1px solid #eee;
        }

        .theme-colors {
            display: flex;
            gap: 12px;
            margin-top: 10px;
        }

        .color-option {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 14px;
            border: 2px solid transparent;
            transition: all 0.3s ease;
        }

        .color-option:hover {
            transform: scale(1.1);
            border-color: #333;
        }

        .section-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .action-btn.small {
            padding: 5px 10px;
            font-size: 0.9rem;
        }

        .objective-item {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
            align-items: center;
        }

        .objective-item input {
            flex: 1;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 6px;
        }

        .remove-btn {
            background: #ffebee;
            color: #e53935;
            border: none;
            width: 36px;
            height: 36px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
        }

        .resource-form .remove-btn {
            background: none;
            color: #e53935;
            padding: 8px 15px;
            width: auto;
            height: auto;
            border-radius: 4px;
            border: 1px solid #ffcdd2;
            margin-top: 10px;
        }

        .image-preview-container {
            position: relative;
            margin-bottom: 15px;
        }

        .image-preview {
            max-width: 100%;
            max-height: 200px;
            border-radius: 8px;
            border: 1px solid #ddd;
            display: block;
            margin-bottom: 10px;
        }

        .change-image-btn {
            background: #e1f0ff;
            color: #2980b9;
            border: 1px solid #cce5ff;
            padding: 8px 15px;
            border-radius: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
            display: inline-flex;
            align-items: center;
            gap: 6px;
            font-size: 0.9rem;
        }

        .change-image-btn:hover {
            background: #3498db;
            color: white;
        }

        .image-upload-area {
            border: 2px dashed #cce5ff;
            border-radius: 8px;
            padding: 25px;
            text-align: center;
            cursor: pointer;
            transition: all 0.3s ease;
            background: #f9fcff;
            margin-bottom: 15px;
        }

        .image-upload-area:hover {
            border-color: #3498db;
            background: #e1f0ff;
        }

        .image-upload-area i {
            font-size: 2.5rem;
            color: #3498db;
            margin-bottom: 10px;
        }

        .image-upload-area p {
            color: #555;
            margin: 0;
        }

        /* 资源上传样式 */
        .resource-header {
            display: flex;
            align-items: center;
            gap: 15px;
            margin-bottom: 15px;
            padding: 10px;
            background: #f9f9f9;
            border-radius: 8px;
        }

        .resource-icon-preview {
            width: 50px;
            height: 50px;
            background: #e1f0ff;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            color: #3498db;
            flex-shrink: 0;
        }

        .resource-info {
            flex: 1;
        }

        .file-info {
            display: flex;
            flex-direction: column;
        }

        .file-size {
            font-size: 0.85rem;
            color: #777;
        }

        .upload-prompt {
            color: #3498db;
            font-weight: 500;
        }

        .upload-btn {
            background: #e1f0ff;
            color: #2980b9;
            border: 1px solid #cce5ff;
            padding: 8px 15px;
            border-radius: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
            display: inline-flex;
            align-items: center;
            gap: 6px;
            font-size: 0.9rem;
        }

        .upload-btn:hover {
            background: #3498db;
            color: white;
        }

        .resource-remove {
            margin-top: 15px;
        }

        /* 表单必填项标识 */
        .required {
            color: #e53935;
            margin-left: 3px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        .form-section {
            background: #f9f9f9;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
        }

        .resource-item {
            padding: 15px;
            border: 1px solid #eee;
            border-radius: 8px;
            margin-bottom: 15px;
            background: white;
        }

        .resource-remove {
            margin-top: 10px;
            width: 100%;
        }

        .form-row {
            display: flex;
            gap: 15px;
            margin-bottom: 15px;
        }

        .form-row .form-group {
            flex: 1;
            margin-bottom: 0;
        }

        /* 增大文本输入框 */
        textarea {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 6px;
            font-size: 1rem;
            min-height: 100px;
            resize: vertical;
        }

        .large-textarea {
            min-height: 200px;
        }

        /* 响应式设计 */
        @media (max-width: 800px) {
            .container {
                flex-direction: column;
            }

            .sidebar {
                width: 100%;
                margin-bottom: 15px;
            }
        }

        @media (max-width: 668px) {
            .navbar {
                padding: 10px 12px;
            }

            .logo-container h1 {
                font-size: 1.3rem;
            }

            .welcome-header {
                flex-direction: column;
                align-items: flex-start;
                gap: 12px;
            }

            .class-selector {
                width: 100%;
            }

            .section-header {
                flex-direction: column;
                align-items: flex-start;
                gap: 12px;
            }

            .action-btn {
                width: 100%;
                justify-content: center;
            }

            .class-grid {
                grid-template-columns: 1fr;
            }

            .action-buttons {
                flex-direction: column;
            }
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 顶部导航栏 -->
        <div class="navbar">
            <div class="logo-container">
                <img src=""
                    alt="LOGO">
                <h1>教师管理系统</h1>
            </div>

            <div class="user-info-container">
                <div class="user-avatar" @click="toggleDropdown">{{ userInitials }}</div>
                <div class="dropdown-menu" :class="{show: isDropdownOpen}">
                    <div class="dropdown-header">
                        <h4>{{ user.name }}</h4>
                    </div>
                    <div class="dropdown-item" @click="editProfile">
                        <i class="fas fa-user-edit"></i>编辑个人信息
                    </div>
                    <div class="dropdown-item" @click="changePassword">
                        <i class="fas fa-key"></i>修改密码
                    </div>
                    <div class="dropdown-divider"></div>
                    <div class="dropdown-item" @click="logout">
                        <i class="fas fa-sign-out-alt"></i>退出登录
                    </div>
                </div>
                <button class="logout-btn" @click="logout">
                    <i class="fas fa-sign-out-alt"></i> 退出
                </button>
            </div>
        </div>

        <!-- 页面容器 -->
        <div class="container">
            <!-- 侧边栏 -->
            <div class="sidebar">
                <div class="sidebar-header">
                    <i class="fas fa-chalkboard-teacher"></i>
                    <h2>教师控制台</h2>
                </div>
                <ul>
                    <li v-for="(item, index) in menuItems" :key="index">
                        <a href="#" :class="{active: activeMenu === item.id}" @click.prevent="setActiveMenu(item.id)">
                            <i :class="item.icon"></i>{{ item.name }}
                        </a>
                    </li>
                </ul>
            </div>

            <!-- 主内容区 -->
            <div class="main-content">
                <div class="welcome-header">
                    <h2>
                        <i class="fas fa-user-graduate"></i>
                        欢迎回来，{{ user.name }}
                    </h2>
                    <div class="class-selector"
                        v-if="activeMenu !== 'settings' && activeMenu !== 'experiments' && activeMenu !== 'dashboard'">
                        <label for="class-select"><i class="fas fa-users"></i> 选择班级：</label>
                        <select id="class-select" v-model="selectedClass">
                            <option v-for="(cls, index) in classes" :key="index" :value="cls.id">
                                {{ cls.name }}
                            </option>
                        </select>
                    </div>
                </div>

                <!-- 控制面板 -->
                <div class="section" v-if="activeMenu === 'dashboard'">
                    <div class="section-header">
                        <h3><i class="fas fa-tachometer-alt"></i> 控制面板</h3>
                    </div>
                    <div class="dashboard-content">
                        <div class="dashboard-card">
                            <i class="fas fa-users"></i>
                            <h4>班级总数</h4>
                            <p>{{ classes.length }}</p>
                        </div>
                        <div class="dashboard-card">
                            <i class="fas fa-flask"></i>
                            <h4>实验总数</h4>
                            <p>{{ experiments.length }}</p>
                        </div>
                        <div class="dashboard-card">
                            <i class="fas fa-check-circle"></i>
                            <h4>待批改报告</h4>
                            <p>{{ pendingReports.length }}</p>
                        </div>
                        <div class="dashboard-card">
                            <i class="fas fa-chart-line"></i>
                            <h4>学生总数</h4>
                            <p>{{ totalStudents }}</p>
                        </div>
                    </div>
                </div>

                <!-- 班级管理 -->
                <div class="section" v-if="activeMenu === 'classes'">
                    <div class="section">
                        <div class="section-header">
                            <h3><i class="fas fa-users"></i> 班级管理</h3>
                            <button class="action-btn" @click="createClass">
                                <i class="fas fa-plus-circle"></i> 东软考勤表导入班级
                            </button>
                        </div>

                        <div class="class-grid">
                            <div class="class-card" v-for="(cls, index) in classes" :key="index">
                                <div class="class-card-header">
                                    <h4>{{ cls.name }}</h4>
                                    <span class="status-badge" :class="{'status-submitted': cls.status === 'active'}">
                                        {{ cls.status === 'active' ? '活跃' : '归档' }}
                                    </span>
                                </div>
                                <p><i class="fas fa-calendar"></i> 创建时间: 2025-08-05</p>

                                <div class="class-stats">
                                    <div class="stat-card">
                                        <div class="stat-value">{{ cls.studentCount }}</div>
                                        <div class="stat-label">学生人数</div>
                                    </div>
                                    <div class="stat-card">
                                        <div class="stat-value">{{ cls.experimentCount }}</div>
                                        <div class="stat-label">实验数量</div>
                                    </div>
                                    <div class="stat-card">
                                        <div class="stat-value">38</div>
                                        <div class="stat-label">已提交报告</div>
                                    </div>
                                    <div class="stat-card">
                                        <div class="stat-value">85%</div>
                                        <div class="stat-label">平均成绩</div>
                                    </div>
                                </div>

                                <div class="class-actions">
                                    <button @click="openExperimentAssignment(cls)">
                                        <i class="fas fa-tasks"></i> 实验分配
                                    </button>
                                    <button @click="openStudentManagement(cls)">
                                        <i class="fas fa-user-graduate"></i> 学生管理
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 上传名单模态框 -->
                <div class="modal" v-if="showUploadModal" @click.self="closeUploadModal">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h3>上传学生名单 - {{ currentClassName }}</h3>
                            <button class="close-btn" @click="closeUploadModal">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>

                        <div class="modal-body">
                            <div class="form-group">
                                <label>输入学生名单</label>
                                <p class="hint-text">格式：学号 姓名 班级（每行一个学生）</p>
                                <textarea class="roster-textarea" v-model="rosterText" placeholder="例如：
2021001 张三 计算机科学与技术1班
2021002 李四 计算机科学与技术1班
2021003 王五 计算机科学与技术1班"></textarea>

                                <div v-if="parseError" class="error-message">
                                    {{ parseError }}
                                </div>

                                <button class="action-btn" @click="parseRoster">
                                    <i class="fas fa-check"></i> 解析名单
                                </button>
                            </div>

                            <div class="roster-preview" v-if="studentsToAdd.length > 0 || studentsToRemove.length > 0">
                                <h4><i class="fas fa-users"></i> 学生名单预览</h4>
                                <p class="hint-text">已解析 {{ studentsToAdd.length }} 名学生</p>

                                <div v-for="(student, index) in studentsToAdd" :key="index" class="student-row">
                                    <div class="student-info">
                                        {{ student.s_no }} - {{ student.s_name }} ({{ student.class_name }})
                                    </div>
                                    <div class="student-actions">
                                        <span class="remove-student" @click="removeStudent(index)">
                                            <i class="fas fa-trash-alt"></i>
                                        </span>
                                    </div>
                                </div>

                                <div class="add-student-form">
                                    <input type="text" v-model="newStudent.s_no" placeholder="学号">
                                    <input type="text" v-model="newStudent.s_name" placeholder="姓名">
                                    <button class="action-btn small" @click="addSingleStudent">
                                        <i class="fas fa-plus"></i> 添加
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="modal-footer">
                            <button class="btn btn-secondary" @click="closeUploadModal">取消</button>
                            <button class="btn btn-primary" @click="submitRoster"
                                :disabled="studentsToAdd.length === 0">
                                <i class="fas fa-save"></i> 提交名单
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 学生管理模态框 -->
                <div class="modal" v-if="showStudentManagement" @click.self="closeStudentManagement">
                    <div class="modal-content student-management-modal">
                        <div class="modal-header">
                            <h3>学生管理 - {{ currentClassForStudents.name }} <span class="cache-indicator"
                                    :class="{cached: currentClassForStudents.cached}">
                                    <i class="fas"
                                        :class="currentClassForStudents.cached ? 'fa-check-circle' : 'fa-sync-alt'"></i>
                                    {{ currentClassForStudents.cached ? '已缓存' : '未缓存' }}
                                </span>
                            </h3>
                            <button class="close-btn" @click="closeStudentManagement">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>

                        <div class="modal-body">
                            <!-- 标签导航 -->
                            <div class="tab-nav">
                                <button :class="{active: currentStudentTab === 'list'}"
                                    @click="currentStudentTab = 'list'">
                                    <i class="fas fa-list"></i> 学生列表
                                </button>
                                <button :class="{active: currentStudentTab === 'import'}"
                                    @click="currentStudentTab = 'import'">
                                    <i class="fas fa-file-import"></i> 导入名单
                                </button>
                            </div>

                            <!-- 学生列表标签页 -->
                            <div class="tab-content" v-if="currentStudentTab === 'list'">
                                <div class="section-header">
                                    <h4><i class="fas fa-user-graduate"></i> 学生名单</h4>
                                    <button class="action-btn small" @click="refreshStudentList">
                                        <i class="fas fa-sync-alt"></i> 刷新列表
                                    </button>
                                </div>

                                <table class="data-table">
                                    <thead>
                                        <tr>
                                            <th>学号</th>
                                            <th>姓名</th>
                                            <th>班级</th>
                                            <th>操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr v-for="(student, idx) in currentClassForStudents.students" :key="idx">
                                            <td>{{ student.s_no }}</td>
                                            <td>{{ student.s_name }}</td>
                                            <td>{{ student.class_name || currentClassForStudents.name }}</td>
                                            <td>
                                                <button @click="removeStudentFromClass(student.id)">
                                                    <i class="fas fa-trash-alt"></i> 移除
                                                </button>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>

                            <!-- 导入名单标签页 -->
                            <div class="tab-content" v-if="currentStudentTab === 'import'">
                                <div class="form-group">
                                    <label>输入学生名单</label>
                                    <p class="hint-text">格式：学号 姓名 班级（每行一个学生）</p>
                                    <textarea class="roster-textarea" v-model="rosterText" placeholder="例如：
2021001 张三 计算机科学与技术1班
2021002 李四 计算机科学与技术1班
2021003 王五 计算机科学与技术1班"></textarea>

                                    <div v-if="parseError" class="error-message">
                                        {{ parseError }}
                                    </div>

                                    <button class="action-btn" @click="parseRoster">
                                        <i class="fas fa-check"></i> 解析名单
                                    </button>
                                </div>

                                <div class="roster-preview"
                                    v-if="studentsToAdd.length > 0 || studentsToRemove.length > 0">
                                    <h4><i class="fas fa-users"></i> 学生名单预览</h4>
                                    <p class="hint-text">已解析 {{ studentsToAdd.length }} 名学生</p>

                                    <div v-for="(student, index) in studentsToAdd" :key="index" class="student-row">
                                        <div class="student-info">
                                            {{ student.s_no }} - {{ student.s_name }} ({{ student.class_name }})
                                        </div>
                                        <div class="student-actions">
                                            <span class="remove-student" @click="removeStudent(index)">
                                                <i class="fas fa-trash-alt"></i>
                                            </span>
                                        </div>
                                    </div>

                                    <div class="add-student-form">
                                        <input type="text" v-model="newStudent.s_no" placeholder="学号">
                                        <input type="text" v-model="newStudent.s_name" placeholder="姓名">
                                        <button class="action-btn small" @click="addSingleStudent">
                                            <i class="fas fa-plus"></i> 添加
                                        </button>
                                    </div>
                                </div>

                                <div class="import-actions">
                                    <button class="btn btn-secondary" @click="currentStudentTab = 'list'">
                                        <i class="fas fa-arrow-left"></i> 返回列表
                                    </button>
                                    <button class="btn btn-primary" @click="submitRoster"
                                        :disabled="studentsToAdd.length === 0">
                                        <i class="fas fa-save"></i> 提交名单
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="modal-footer">
                            <button class="btn btn-primary" @click="closeStudentManagement">
                                完成
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 实验分配模态框 -->
                <div class="modal" v-if="showExperimentAssignment" @click.self="closeExperimentAssignment">
                    <div class="modal-content wide-modal">
                        <div class="modal-header">
                            <h3>实验分配 - {{ currentClassForExperiments.name }}</h3>
                            <button class="close-btn" @click="closeExperimentAssignment">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>

                        <div class="modal-body">
                            <div class="section-header">
                                <h4><i class="fas fa-flask"></i> 已分配实验</h4>
                                <button class="action-btn small" @click="showAddExperiment=true">
                                    <i class="fas fa-plus"></i> 添加实验
                                </button>
                            </div>

                            <table class="data-table">
                                <thead>
                                    <tr>
                                        <th>实验名称</th>
                                        <th>截止日期</th>
                                        <th>操作</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr v-for="(exp, idx) in classExperiments" :key="idx">
                                        <td>{{ exp.title }}</td>
                                        <td>
                                            <!-- 修改此处：使用localDeadline -->
                                            <input type="date" v-model="exp.localDeadline"
                                                @change="updateDeadline(exp)">
                                        </td>
                                        <td>
                                            <button @click="removeExperiment(exp.id)">
                                                <i class="fas fa-trash-alt"></i> 移除
                                            </button>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>

                            <!-- 添加实验面板 -->
                            <div v-if="showAddExperiment" class="add-experiment-panel">
                                <div class="form-group">
                                    <label>选择实验</label>
                                    <select v-model="selectedExperimentToAdd">
                                        <option v-for="exp in availableExperiments" :key="exp.id" :value="exp">
                                            {{ exp.title }} ({{ exp.course_name }})
                                        </option>
                                    </select>
                                </div>

                                <div class="form-group">
                                    <label>截止日期</label>
                                    <input type="date" v-model="newExperimentDeadline">
                                </div>

                                <div class="action-buttons">
                                    <button class="btn btn-secondary" @click="showAddExperiment=false">
                                        取消
                                    </button>
                                    <button class="btn btn-primary" @click="assignExperiment">
                                        <i class="fas fa-plus"></i> 分配实验
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="modal-footer">
                            <button class="btn btn-primary" @click="closeExperimentAssignment">
                                完成
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 实验批改 -->
                <div class="section" v-if="activeMenu === 'grading'">
                    <div class="section">
                        <div class="section-header">
                            <h3><i class="fas fa-check-circle"></i> 待批改实验</h3>
                            <button class="action-btn" @click="refreshPendingReports">
                                <i class="fas fa-sync-alt"></i> 刷新列表
                            </button>
                        </div>

                        <!-- 添加实验选择下拉菜单 -->
                        <div class="class-selector">
                            <label for="experiment-select"><i class="fas fa-flask"></i> 选择实验：</label>
                            <select id="experiment-select" v-model="selectedExperiment" @change="loadExperimentGrades">
                                <option v-for="exp in classExperiments" :key="exp.id" :value="exp.id">
                                    {{ exp.title }}
                                </option>
                            </select>
                        </div>

                        <!-- 成绩批改表格 -->
                        <table class="data-table" v-if="gradingData.length > 0">
                            <thead>
                                <tr>
                                    <th>学号</th>
                                    <th>姓名</th>
                                    <th v-for="criteria in criteriaList" :key="criteria.id">
                                        {{ criteria.name }} ({{ criteria.proportion }}%)
                                    </th>
                                    <th>总分</th>
                                    <th>操作</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr v-for="(student, index) in gradingData" :key="index">
                                    <td>{{ student.s_no }}</td>
                                    <td>{{ student.s_name }}</td>
                                    <td v-for="criteria in criteriaList" :key="criteria.id">
                                        <input type="number" min="0" max="100" step="0.1"
                                            v-model="student.grades[criteria.id]" class="grade-input">
                                    </td>
                                    <td>{{ calculateTotalScore(student) }}</td>
                                    <td>
                                        <button @click="saveStudentGrades(student)">
                                            <i class="fas fa-save"></i> 保存
                                        </button>
                                    </td>
                                </tr>
                            </tbody>
                        </table>

                        <div v-if="gradingData.length === 0 && !loadingGrades" class="no-data">
                            <p>没有可批改的成绩数据</p>
                        </div>
                        <div class="loading-container" v-if="loadingGrades">
                            <div class="loading-spinner"></div>
                        </div>
                    </div>
                </div>

                <!-- 成绩管理 -->
                <div class="section" v-if="activeMenu === 'grades'">
                    <div class="section-header">
                        <h3><i class="fas fa-chart-line"></i> 成绩管理</h3>
                        <button class="action-btn" @click="exportGrades">
                            <i class="fas fa-file-excel"></i> 导出成绩
                        </button>
                    </div>

                    <table class="data-table">
                        <thead>
                            <tr>
                                <th>学号</th>
                                <th>姓名</th>
                                <th v-for="(experiment, idx) in classGrades.experiments" :key="experiment.id">
                                    实验{{ idx+1 }}<br>{{ experiment.title }}
                                </th>
                                <th>操作</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="student in classGrades.students" :key="student.id">
                                <td>{{ student.s_no }}</td>
                                <td>{{ student.s_name }}</td>

                                <td v-for="experiment in classGrades.experiments" :key="experiment.id">
                                    <span class="grade-badge">
                                        {{ getStudentGrade(student, experiment.id) }}
                                    </span>
                                </td>

                                <td>
                                    <button @click="viewStudentDetails(student)">
                                        <i class="fas fa-eye"></i> 详情
                                    </button>
                                </td>
                            </tr>
                        </tbody>
                    </table>

                    <div v-if="classGrades.students.length === 0" class="no-data">
                        <p>暂无学生成绩数据</p>
                    </div>
                </div>

                <!-- 实验管理 -->
                <div class="section" v-if="activeMenu === 'experiments'">
                    <div class="section-header">
                        <h3><i class="fas fa-flask"></i> 实验管理</h3>
                        <button class="action-btn" @click="openCreateExperimentModal">
                            <i class="fas fa-plus-circle"></i> 创建新实验
                        </button>
                    </div>

                    <table class="data-table">
                        <thead>
                            <tr>
                                <th>课程名称</th>
                                <th>实验名称</th>
                                <th>实验时长(小时)</th>
                                <th>关联班级数</th>
                                <th>操作</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="(experiment, index) in experiments" :key="index">
                                <td>{{ experiment.course_name }}</td>
                                <td>{{ experiment.title }}</td>
                                <td>{{ experiment.duration }}</td>
                                <td>{{ experiment.classCount }}</td>
                                <td>
                                    <div class="action-buttons">
                                        <button @click="viewExperimentDetails(experiment)">
                                            <i class="fas fa-eye"></i> 详情
                                        </button>
                                        <button @click="editExperiment(experiment)">
                                            <i class="fas fa-edit"></i> 编辑
                                        </button>
                                        <button @click="deleteExperiment(experiment)"
                                            :disabled="experiment.classCount > 0"
                                            :title="experiment.classCount > 0 ? '该实验已被班级关联，无法删除' : ''">
                                            <i class="fas fa-trash-alt"></i> 删除
                                        </button>
                                    </div>
                                </td>
                            </tr>
                        </tbody>
                    </table>

                    <div class="loading-container" v-if="loadingExperiments">
                        <div class="loading-spinner"></div>
                    </div>

                    <div v-if="experiments.length === 0 && !loadingExperiments" class="no-data">
                        <p>暂无实验数据</p>
                    </div>
                </div>

                <!-- 实验详情模态框 -->
                <div class="modal" v-if="showExperimentModal" @click.self="closeExperimentModal">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h3>{{ currentExperiment.title }}</h3>
                            <button class="close-btn" @click="closeExperimentModal">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>

                        <div class="modal-body">
                            <div class="modal-section">
                                <h4><i class="fas fa-info-circle"></i> 基本信息</h4>
                                <p><strong>课程类别：</strong> {{ currentExperiment.course_category === 'cs' ? '计算机' : '人工智能'
                                    }}</p>
                                <p><strong>实验时长：</strong> {{ currentExperiment.duration }} 小时</p>
                                <p><strong>发布时间：</strong> {{ formatDate(currentExperiment.publish_date) }}</p>
                                <p><strong>简短描述：</strong> {{ currentExperiment.short_description }}</p>
                                <p><strong>详细描述：</strong> {{ currentExperiment.full_description }}</p>
                            </div>

                            <div class="modal-section">
                                <h4><i class="fas fa-bullseye"></i> 实验目标</h4>
                                <ul>
                                    <li v-for="(objective, idx) in currentExperiment.objectives" :key="idx">
                                        {{ objective.objective }}
                                    </li>
                                </ul>
                            </div>

                            <div class="modal-section">
                                <h4><i class="fas fa-file-download"></i> 实验资源</h4>
                                <div class="resource-grid">
                                    <div class="resource-card" v-for="(resource, idx) in currentExperiment.resources"
                                        :key="idx">
                                        <div class="resource-icon">
                                            <i :class="getResourceIcon(resource.type)"></i>
                                        </div>
                                        <div class="resource-info">
                                            <strong>{{ resource.name }}</strong>
                                            <p>{{ resource.type | capitalize }}文件</p>
                                            <p v-if="resource.is_public == 1" class="public-badge">公开</p>
                                            <p v-else class="private-badge">仅班级可见</p>
                                            <a :href="resource.file_path" target="_blank" v-if="resource.file_path">
                                                下载资源
                                            </a>
                                            <p v-else>文件路径无效</p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="modal-footer">
                            <button class="btn btn-secondary" @click="closeExperimentModal">关闭</button>
                            <button class="btn btn-primary" @click="editExperiment(currentExperiment)">编辑实验</button>
                        </div>
                    </div>
                </div>

                <!-- 添加/编辑实验模态框 -->
                <div class="modal" v-if="showEditExperimentModal" @click.self="closeEditExperimentModal">
                    <div class="modal-content wide-modal">
                        <div class="modal-header">
                            <h3>{{ isEditingExperiment ? '编辑实验' : '添加新实验' }}</h3>
                            <button class="close-btn" @click="closeEditExperimentModal">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>

                        <div class="modal-body">
                            <div class="form-group">
                                <label>实验标题</label>
                                <input type="text" v-model="editExperimentData.title" placeholder="输入实验标题">
                            </div>

                            <div class="form-group">
                                <label>课程类别</label>
                                <select v-model="editExperimentData.course_category">
                                    <option value="cs">计算机</option>
                                    <option value="ai">人工智能</option>
                                </select>
                            </div>

                            <div class="form-group">
                                <label>实验时长(小时)</label>
                                <input type="number" v-model="editExperimentData.duration" min="1" max="20">
                            </div>

                            <div class="form-group">
                                <label>封面图片</label>
                                <div v-if="editExperimentData.image_url" class="image-preview-container">
                                    <img :src="editExperimentData.image_url" alt="封面图片" class="image-preview">
                                    <button type="button" class="change-image-btn" @click="triggerCoverUpload">
                                        <i class="fas fa-sync-alt"></i> 更换图片
                                    </button>
                                </div>
                                <div v-else class="image-upload-area" @click="triggerCoverUpload">
                                    <i class="fas fa-cloud-upload-alt"></i>
                                    <p>点击上传封面图片</p>
                                </div>
                                <input type="file" ref="coverUpload" accept="image/*" style="display: none"
                                    @change="handleCoverUpload">
                            </div>

                            <div class="form-group">
                                <label>简短描述</label>
                                <textarea v-model="editExperimentData.short_description" placeholder="输入简短描述(最多200字)"
                                    rows="3" maxlength="200"></textarea>
                            </div>

                            <div class="form-group">
                                <label>详细描述</label>
                                <textarea v-model="editExperimentData.full_description" placeholder="输入详细描述" rows="5"
                                    class="large-textarea"></textarea>
                            </div>

                            <div class="form-section">
                                <div class="section-header">
                                    <h4><i class="fas fa-bullseye"></i> 实验目标</h4>
                                    <button type="button" class="action-btn small" @click="addObjective">
                                        <i class="fas fa-plus"></i> 添加目标
                                    </button>
                                </div>

                                <div class="objective-item" v-for="(objective, index) in editExperimentData.objectives"
                                    :key="index">
                                    <input type="text" v-model="objective.objective" placeholder="输入实验目标"
                                        @keyup.enter="addObjective">
                                    <button class="remove-btn" @click="removeObjective(index)">
                                        <i class="fas fa-times"></i>
                                    </button>
                                </div>
                            </div>

                            <div class="form-section">
                                <div class="section-header">
                                    <h4><i class="fas fa-file-download"></i> 实验资源</h4>
                                    <button type="button" class="action-btn small" @click="addResource">
                                        <i class="fas fa-plus"></i> 添加资源
                                    </button>
                                </div>

                                <div class="resource-form" v-for="(resource, index) in editExperimentData.resources"
                                    :key="index">
                                    <div class="resource-item">
                                        <div class="resource-header">
                                            <div class="resource-icon-preview">
                                                <i :class="getResourceIcon(resource.type)"></i>
                                            </div>
                                            <div class="resource-info">
                                                <div v-if="resource.file" class="file-info">
                                                    <strong>{{ resource.file.name }}</strong>
                                                    <span class="file-size">{{ formatFileSize(resource.file.size)
                                                        }}</span>
                                                </div>
                                                <div v-else class="upload-prompt">
                                                    <i class="fas fa-upload"></i> 请上传文件
                                                </div>
                                            </div>
                                        </div>

                                        <div class="form-row">
                                            <div class="form-group">
                                                <label>资源名称 <span class="required">*</span></label>
                                                <input type="text" v-model="resource.name" placeholder="输入资源名称"
                                                    required>
                                            </div>

                                            <div class="form-group">
                                                <label>资源类型 <span class="required">*</span></label>
                                                <select v-model="resource.type">
                                                    <option value="pdf">PDF</option>
                                                    <option value="docx">Word</option>
                                                    <option value="code">代码</option>
                                                    <option value="video">视频</option>
                                                    <option value="image">图片</option>
                                                    <option value="other">其他</option>
                                                </select>
                                            </div>
                                        </div>

                                        <div class="form-row">
                                            <div class="form-group">
                                                <button type="button" class="upload-btn"
                                                    @click="triggerResourceUpload(index)">
                                                    <i class="fas fa-cloud-upload-alt"></i> {{ resource.file ? '重新上传' :
                                                    '上传文件' }}
                                                </button>
                                                <input type="file" :ref="'resourceUpload'+index" style="display: none"
                                                    @change="(event) => handleResourceUpload(event, index)">
                                            </div>

                                            <div class="form-group">
                                                <label>
                                                    <input type="checkbox" v-model="resource.is_public"> 公开资源
                                                </label>
                                            </div>
                                        </div>
                                    </div>

                                    <button class="remove-btn resource-remove" @click="removeResource(index)">
                                        <i class="fas fa-trash-alt"></i> 删除资源
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div class="modal-footer">
                            <button class="btn btn-secondary" @click="closeEditExperimentModal">取消</button>
                            <button class="btn btn-primary" @click="saveExperiment">
                                {{ isEditingExperiment ? '保存修改' : '创建实验' }}
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 系统设置 -->
                <div class="section" v-if="activeMenu === 'settings'">
                    <div class="section-header">
                        <h3><i class="fas fa-cog"></i> 系统设置</h3>
                    </div>
                    <div class="settings-content">
                        <div class="setting-item">
                            <h4><i class="fas fa-user-cog"></i> 账户设置</h4>
                            <div class="form-group">
                                <label>通知设置</label>
                                <select v-model="settings.notifications">
                                    <option value="all">所有通知</option>
                                    <option value="important">仅重要通知</option>
                                    <option value="none">无通知</option>
                                </select>
                            </div>
                        </div>

                        <div class="setting-item">
                            <h4><i class="fas fa-bell"></i> 消息提醒</h4>
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" v-model="settings.emailAlerts">
                                    邮件提醒
                                </label>
                            </div>
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" v-model="settings.pushAlerts">
                                    推送通知
                                </label>
                            </div>
                        </div>

                        <div class="setting-item">
                            <h4><i class="fas fa-palette"></i> 界面设置</h4>
                            <div class="form-group">
                                <label>主题颜色</label>
                                <div class="theme-colors">
                                    <div class="color-option" v-for="color in themeColors" :key="color"
                                        :style="{backgroundColor: color}" @click="settings.themeColor = color">
                                        <i class="fas fa-check" v-if="settings.themeColor === color"></i>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <button class="action-btn" @click="saveSettings">
                            <i class="fas fa-save"></i> 保存设置
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                // 用户信息
                user: {
                    name: '张教授',
                    email: 'zhang@university.edu',
                    department: '计算机科学与技术学院',
                    initials: 'Z'
                },

                // 菜单项
                menuItems: [
                    { id: 'dashboard', name: '控制面板', icon: 'fas fa-tachometer-alt' },
                    { id: 'classes', name: '班级管理', icon: 'fas fa-users' },
                    { id: 'grading', name: '实验批改', icon: 'fas fa-check-circle' },
                    { id: 'grades', name: '成绩管理', icon: 'fas fa-chart-line' },
                    { id: 'experiments', name: '实验管理', icon: 'fas fa-flask' },
                    { id: 'settings', name: '系统设置', icon: 'fas fa-cog' }
                ],
                activeMenu: 'dashboard',
                isDropdownOpen: false,

                // 班级信息
                classes: [],
                classExperiments: [],       // 当前班级的实验列表
                loadingClasses: false,
                selectedClass: 'c1',
                // 上传名单相关数据
                showUploadModal: false,
                //currentClassId: null,
                //currentClassName: '',

                // 学生管理模态框
                showStudentManagement: false,
                currentClassForStudents: null,
                currentStudentTab: 'list', // 'list' 或 'import'
                rosterText: '',
                parseError: '',
                studentsToAdd: [],
                studentsToRemove: [],
                newStudent: {
                    s_no: '',
                    s_name: '',
                    class_name: ''
                },
                totalStudents: 0,           // 班级总人数
                studentCache: {},

                // 实验分配模态框
                showExperimentAssignment: false,
                showAddExperiment: false,
                selectedExperimentToAdd: null,
                newExperimentDeadline: '',
                availableExperiments: [],
                currentClassForExperiments: null,

                // 待批改实验报告
                pendingReports: [],
                loadingReports: true,

                // 成绩数据
                classGrades: {
                    experiments: [],
                    students: []
                },
                selectedExperiment: null,   // 当前选中的实验ID
                criteriaList: [],           // 当前实验的评分标准
                gradingData: [],            // 当前批改的数据
                loadingGrades: false,        // 加载成绩的状态

                // 实验管理相关数据
                experiments: [],
                loadingExperiments: false,
                showExperimentModal: false,
                showEditExperimentModal: false,
                isEditingExperiment: false,
                currentExperiment: {
                    title: '',
                    course_category: 'cs',
                    duration: 0,
                    publish_date: '',
                    objectives: [],
                    resources: [],
                    classes: []
                },
                editExperimentData: {
                    title: '',
                    short_description: '',
                    full_description: '',
                    course_category: 'cs',
                    duration: 1,
                    image_url: '',
                    objectives: [],
                    resources: []
                },


                // 新增设置相关数据
                settings: {
                    notifications: 'all',
                    emailAlerts: true,
                    pushAlerts: true,
                    themeColor: '#3498db'
                },
                themeColors: ['#3498db', '#2ecc71', '#e74c3c', '#9b59b6', '#1abc9c', '#f39c12'],

                // 加载状态
                loading: false
            },

            computed: {
                // 用户首字母
                userInitials() {
                    return this.user.name ? this.user.name.charAt(0).toUpperCase() : 'T';
                },

                // 当前选择的班级文本
                selectedClassText() {
                    const selected = this.classes.find(cls => cls.id === this.selectedClass);
                    return selected ? selected.name : '未选择班级';
                },

                // 控制面板数据
                dashboardData() {
                    return {
                        classCount: this.classes.length,
                        experimentCount: this.classExperiments.length,
                        pendingReportCount: this.pendingReports.length,
                        totalStudents: this.totalStudents
                    }
                }
            },

            created() {
                // 页面加载时从会话中获取用户信息
                this.loadUserFromSession();
                // 组件创建时获取班级信息
                this.loadClasses();

                // 初始化实验数据
                this.experiments = [];
                this.classExperiments = [];
            },

            // 监听activeMenu变化
            watch: {
                activeMenu(newVal) {
                    // 当菜单变化时加载相应数据
                    switch (newVal) {
                        case 'classes':
                            this.loadClasses();
                            break;
                        case 'grading':
                            this.loadClassExperiments();
                            break;
                        case 'grades':
                            if (this.selectedClass) {
                                this.fetchClassGrades();
                            }
                            break;
                        case 'experiments':
                            this.loadExperiments();
                            break;
                        case 'settings':
                            this.loadSettings();
                            break;
                    }
                },
                selectedClass(newClassId) {
                    if (this.activeMenu === 'grades' && newClassId) {
                        this.fetchClassGrades();
                    }
                }
            },

            // 添加过滤器
            filters: {
                capitalize(value) {
                    if (!value) return '';
                    value = value.toString();
                    return value.charAt(0).toUpperCase() + value.slice(1);
                }
            },

            methods: {
                // 从会话中加载用户信息
                loadUserFromSession() {
                    // 兼容不同key的用户信息
                    let sessionUser = null;
                    if (sessionStorage.getItem('userInfo')) {
                        sessionUser = JSON.parse(sessionStorage.getItem('userInfo'));
                        this.user.name = sessionUser.name;
                        this.user.employeeId = sessionUser.id;
                        this.user.role = sessionUser.role;
                    }
                },

                getAuthToken() {
                    const token = localStorage.getItem('authToken') || sessionStorage.getItem('authToken');
                    if (!token) {
                        throw new Error('登录凭证已过期，请重新登录');
                    }
                    return token;
                },

                async loadClasses() {
                    this.loading = true;
                    this.error = null;
                    try {
                        // 从本地存储获取 token
                        const token = this.getAuthToken();

                        if (!token) {
                            throw new Error('登录凭证已过期，请重新登录');
                        }

                        // 添加认证头
                        const response = await axios.get('/api/teacher/classes', {
                            headers: {
                                Authorization: `Bearer ${token}`
                            }
                        });

                        try {
                            // 处理响应数据
                            this.classes = response.data.classes;
                            // 设置默认选中的班级
                            if (this.classes.length > 0) {
                                this.selectedClass = this.classes[0].id;
                            }

                        } catch (err) {
                            this.error = '无法加载班级数据: ' + (err.response?.data?.message || err.message);
                        } finally {
                            this.loading = false;
                        }
                    } catch (err) {
                        // 处理 401 错误
                        if (err.response?.status === 401) {
                            this.error = '登录已过期，请重新登录';
                            setTimeout(() => window.location.href = '/login.html', 5000);
                        } else {
                            this.error = '无法加载班级信息: ' + (err.response?.data?.message || err.message);
                        }
                    } finally {
                        this.loading = false;
                    }
                },

                // 创建新班级
                createClass() {
                    window.location.href = 'create-class.html';
                },

                // 查看班级详情
                viewClass(classId) {
                    alert(`查看班级管理: ${classId}`);
                },

                async fetchClassStudents(classId) {
                    try {
                        this.loading = true;
                        const token = this.getAuthToken();
                        const response = await axios.get(`/api/teacher/class/${classId}/students`, {
                            headers: { Authorization: `Bearer ${token}` }
                        });

                        return response.data;
                    } catch (error) {
                        console.error('获取学生列表失败:', error);
                        alert('获取学生列表失败，请重试');
                    }
                },

                // 打开实验分配模态框
                openExperimentAssignment(cls) {
                    if (cls && typeof cls === 'object') {
                        this.currentClassForExperiments = { ...cls };
                        this.showExperimentAssignment = true;
                        this.selectedExperimentToAdd = null;
                        this.newExperimentDeadline = '';
                        this.availableExperiments = [];
                        this.fetchAvailableExperiments();
                    }
                },

                // 关闭实验分配模态框
                closeExperimentAssignment() {
                    this.showExperimentAssignment = false;
                },

                // 加载可分配的实验
                async fetchAvailableExperiments() {
                },

                async fetchClassGrades() {
                    try {
                        this.loading = true;
                        const token = this.getAuthToken();
                        const response = await axios.get(`/api/teacher/grades/${this.selectedClass}`, {
                            headers: { Authorization: `Bearer ${token}` }
                        });

                        this.classGrades = response.data;
                    } catch (error) {
                        console.error('获取成绩失败:', error);
                        alert('获取成绩失败，请重试');
                    } finally {
                        this.loading = false;
                    }
                },

                getStudentGrade(student, experimentId) {
                    return student.grades[experimentId] || '-';
                },

                // 打开上传名单模态框
                /*
                openUploadModal(classId) {
                    console.log("openUploadModal classId: ", classId);
                    const cls = this.classes.find(c => c.id === classId);
                    if (cls) {
                        this.currentClassId = classId;
                        this.currentClassName = cls.name;
                        this.rosterText = '';
                        this.studentsToAdd = [];
                        this.studentsToRemove = [];
                        this.parseError = '';
                        this.newStudent = {
                            s_no: '',
                            s_name: '',
                            class_name: cls.name
                        };
                        this.showUploadModal = true;
                    }
                },*/

                // 关闭上传名单模态框
                closeUploadModal() {
                    this.showUploadModal = false;
                },

                // 解析学生名单文本
                parseRoster() {
                    this.parseError = '';
                    this.studentsToAdd = [];

                    if (!this.rosterText.trim()) {
                        this.parseError = '请输入学生名单';
                        return;
                    }

                    const lines = this.rosterText.trim().split('\n');
                    const classRegex = /^\d+\s+\S+\s+\S+.*$/; // 验证格式：数字 非空字符 非空字符

                    for (let i = 0; i < lines.length; i++) {
                        const line = lines[i].trim();
                        if (!line) continue;

                        // 验证格式
                        if (!classRegex.test(line)) {
                            this.parseError = `第 ${i + 1} 行格式不正确: "${line}"`;
                            return;
                        }

                        // 分割学生信息
                        const parts = line.split(/\s+/);
                        if (parts.length < 3) {
                            this.parseError = `第 ${i + 1} 行格式不正确: "${line}"`;
                            return;
                        }

                        const s_no = parts[0];
                        const s_name = parts[1];
                        const class_name = parts.slice(2).join(' '); // 班级名称可能包含空格

                        // 检查是否重复
                        const isDuplicate = this.studentsToAdd.some(
                            s => s.s_no === s_no && s.class_name === class_name
                        );

                        if (!isDuplicate) {
                            this.studentsToAdd.push({
                                s_no,
                                s_name,
                                class_name
                            });
                        }
                    }

                    if (this.studentsToAdd.length === 0) {
                        this.parseError = '未发现有效学生记录';
                    }
                },

                // 移除学生
                removeStudent(index) {
                    this.studentsToAdd.splice(index, 1);
                },

                // 添加单个学生
                addSingleStudent() {
                    if (!this.newStudent.s_no || !this.newStudent.s_name) {
                        this.parseError = '请填写学号和姓名';
                        return;
                    }

                    // 检查是否重复
                    const isDuplicate = this.studentsToAdd.some(
                        s => s.s_no === this.newStudent.s_no &&
                            s.class_name === this.currentClassName
                    );

                    if (isDuplicate) {
                        this.parseError = '该学号已存在';
                        return;
                    }

                    this.studentsToAdd.push({
                        s_no: this.newStudent.s_no,
                        s_name: this.newStudent.s_name,
                        class_name: this.currentClassName
                    });

                    // 清空表单
                    this.newStudent.s_no = '';
                    this.newStudent.s_name = '';
                    this.parseError = '';
                },

                // 提交名单到后端
                async submitRoster() {
                    if (this.studentsToAdd.length === 0) {
                        this.parseError = '没有学生可添加';
                        return;
                    }
                    const cls = this.currentClassForStudents;
                    console.log("this.currentClassId: ", cls.id, cls.name);

                    try {
                        const token = this.getAuthToken();
                        const response = await axios.post(
                            '/api/teacher/class/update-roster',
                            {
                                classId: cls.id,
                                students: this.studentsToAdd
                            },
                            {
                                headers: { Authorization: `Bearer ${token}` }
                            }
                        );

                        if (response.data.success) {
                            alert('学生名单上传成功！');
                            this.closeUploadModal();
                            // 刷新班级数据
                            this.loadClasses();

                            const classIndex = this.classes.findIndex(c => c.id === this.currentClassId);
                            if (classIndex !== -1) {
                                this.classes[classIndex].studentCount = this.studentsToAdd.length;
                            }
                        } else {
                            this.parseError = response.data.message || '上传失败，请重试';
                        }
                    } catch (error) {
                        console.error('上传名单失败:', error);
                        this.parseError = '上传失败：' + (error.response?.data?.message || error.message);
                    }
                },

                // 打开学生管理模态框
                async openStudentManagement(cls) {
                    this.currentClassForStudents = {
                        ...cls,
                        cached: false,
                        students: [],
                        loading: true
                    };

                    // 检查是否有缓存
                    if (this.studentCache[cls.id]) {
                        this.currentClassForStudents.students = this.studentCache[cls.id].students;
                        this.currentClassForStudents.cached = true;
                        this.currentClassForStudents.loading = false;
                    } else {
                        const students = await this.fetchClassStudents(cls.id);

                        this.currentClassForStudents.students = students;
                        this.currentClassForStudents.loading = false;

                        // 缓存学生列表
                        this.studentCache[cls.id] = {
                            timestamp: new Date().getTime(),
                            students: [...students]
                        };
                        this.currentClassForStudents.cached = true;
                    }
                    this.showStudentManagement = true;
                    this.currentStudentTab = 'list';
                },

                // 刷新学生列表
                async refreshStudentList() {
                    if (!this.currentClassForStudents) return;

                    const cls = this.currentClassForStudents; // 使用当前班级对象
                    this.currentClassForStudents.loading = true;
                    this.currentClassForStudents.cached = false;

                    try {
                        const students = await this.fetchClassStudents(cls.id);
                        this.currentClassForStudents.students = students;
                        this.currentClassForStudents.loading = false;

                        // 更新缓存
                        this.studentCache[cls.id] = {
                            timestamp: new Date().getTime(),
                            students: [...students]
                        };
                        this.currentClassForStudents.cached = true;
                    } catch (error) {
                        console.error('刷新学生列表失败:', error);
                        this.currentClassForStudents.loading = false;
                    }
                },

                // 关闭学生管理模态框
                closeStudentManagement() {
                    this.showStudentManagement = false;
                    this.currentClassForStudents = null;
                },

                // 打开实验分配模态框
                openExperimentAssignment(cls) {
                    if (cls && typeof cls === 'object') {
                        this.currentClassForExperiments = { ...cls };
                        this.showExperimentAssignment = true;
                        // 加载可用实验列表（排除已分配的）
                        this.loadAvailableExperiments(cls.id);
                    } else {
                        console.error('Invalid class object:', cls);
                    }
                },

                // 关闭实验分配模态框
                closeExperimentAssignment() {
                    this.showExperimentAssignment = false;
                    this.currentClassForExperiments = null;
                    this.showAddExperiment = false;
                },

                // 加载可选实验（差集计算）
                async loadAvailableExperiments() {
                    if (this.experiments.length === 0) {
                        try {
                            const token = this.getAuthToken();
                            const response = await axios.get('/api/teacher/experiments', {
                                headers: { Authorization: `Bearer ${token}` }
                            });

                            // 更新全局实验列表 - 确保是数组
                            this.experiments = Array.isArray(response.data.data)
                                ? response.data.data
                                : [];
                        } catch (error) {
                            this.experiments = []; // 确保是数组
                        }
                    }
                    const availableExps = this.experiments;

                    if (this.classExperiments.length === 0) {
                        try {
                            const token = this.getAuthToken();
                            const response = await axios.get(`/api/teacher/class/${this.selectedClass}/experiments`, {
                                headers: { Authorization: `Bearer ${token}` }
                            });

                            this.classExperiments = response.data.map(exp => ({
                                ...exp,
                                localDeadline: this.formatDateForInput(exp.deadline)
                            }));
                        } catch (error) {
                            console.error('加载班级实验失败:', error);
                        }
                    }

                    const assignedIds = new Set(this.classExperiments.map(exp => exp.id));
                    // 计算差集: 所有实验 - 已分配实验
                    this.availableExperiments = availableExps.filter(
                        exp => exp && exp.id && !assignedIds.has(exp.id)
                    );
                },

                // 添加学生
                async addStudentToClass() {
                    if (!this.newStudent.s_no || !this.newStudent.s_name) {
                        alert('请填写完整信息');
                        return;
                    }

                    // API调用添加学生
                    await axios.post(`/api/class/${this.currentClassForStudents.id}/students`, this.newStudent);

                    // 更新本地数据
                    this.currentClassForStudents.students.push({ ...this.newStudent });
                    this.newStudent = { s_no: '', s_name: '' };
                },

                // 移除学生
                async removeStudentFromClass(studentId) {
                    if (!confirm('确定要移除该学生吗？')) return;
                    console.log("remove student with id: " + "studentId");

                    try {
                        const token = this.getAuthToken();
                        await axios.delete(
                            `/api/teacher/remove-student/${this.currentClassForStudents.id}/${studentId}`,
                            {
                                headers: { Authorization: `Bearer ${token}` }
                            }
                        );

                        this.currentClassForStudents.students = this.currentClassForStudents.students.filter(
                            s => s.id !== studentId
                        );

                        const classIndex = this.classes.findIndex(c => c.id === this.currentClassForStudents.id);
                        if (classIndex !== -1) {
                            this.classes[classIndex].studentCount--;
                        }

                        alert('学生已移除');
                    } catch (error) {
                        console.error('移除学生失败:', error);
                        alert('移除学生失败');
                    }
                },

                // 分配实验
                async assignExperiment() {
                    if (!this.selectedExperimentToAdd || !this.newExperimentDeadline) {
                        alert('请选择实验并设置截止日期');
                        return;
                    }

                    const assignment = {
                        experimentId: this.selectedExperimentToAdd.id,
                        classId: this.currentClassForExperiments.id,
                        deadline: this.newExperimentDeadline
                    };

                    // API调用分配实验
                    try {
                        const token = this.getAuthToken();
                        const response = await axios.post('/api/teacher/class/assign-experiment', assignment, {
                            headers: { Authorization: `Bearer ${token}` }
                        });

                        // 更新本地数据
                        this.classExperiments.push({
                            ...this.selectedExperimentToAdd,
                            deadline: this.newExperimentDeadline
                        });

                        // === 更新班级实验数量 ===
                        const classIndex = this.classes.findIndex(c => c.id === this.currentClassForExperiments.id);
                        if (classIndex !== -1) {
                            this.classes[classIndex].experimentCount++;
                        }
                    } catch (error) {
                        console.error('分配实验失败:', error);
                        alert('分配实验失败');
                    } finally {
                        this.showExperimentAssignment = false;
                        this.currentClassForExperiments = null;
                        this.showAddExperiment = false;
                    };

                    // 重置状态
                    this.showAddExperiment = false;
                    this.selectedExperimentToAdd = null;
                    this.newExperimentDeadline = '';
                },

                // 添加日期格式化方法
                formatDateForInput(isoString) {
                    if (!isoString) return '';
                    const date = new Date(isoString);
                    const year = date.getFullYear();
                    const month = String(date.getMonth() + 1).padStart(2, '0');
                    const day = String(date.getDate()).padStart(2, '0');
                    return `${year}-${month}-${day}`;
                },

                // 修改更新截止日期的方法
                async updateDeadline(experiment) {
                    // 将本地日期格式转换为ISO字符串
                    const isoDeadline = new Date(experiment.localDeadline + 'T00:00:00Z').toISOString();

                    // 更新原始数据
                    experiment.deadline = isoDeadline;

                    try {
                        const token = this.getAuthToken();
                        await axios.put(`/api/class/assignment/${experiment.assignmentId}`, {
                            deadline: isoDeadline
                        }, {
                            headers: { Authorization: `Bearer ${token}` }
                        });
                    } catch (error) {
                        console.error('更新截止日期失败:', error);
                        alert('更新失败');
                    }
                },

                // 修改加载班级实验的方法
                async loadClassExperiments() {
                    if (!this.selectedClass) return;

                    try {
                        const token = this.getAuthToken();
                        const response = await axios.get(`/api/teacher/class/${this.selectedClass}/experiments`, {
                            headers: { Authorization: `Bearer ${token}` }
                        });

                        // 为每个实验添加localDeadline字段
                        this.classExperiments = response.data.map(exp => ({
                            ...exp,
                            localDeadline: this.formatDateForInput(exp.deadline)
                        }));

                        if (this.classExperiments.length > 0) {
                            this.selectedExperiment = this.classExperiments[0].id;
                            this.loadExperimentGrades();
                        }
                    } catch (error) {
                        console.error('加载班级实验失败:', error);
                    }
                },

                // 移除实验
                async removeExperiment(experimentId) {
                    if (!confirm('确定要移除该实验吗？')) return;

                    try {
                        const token = this.getAuthToken();
                        await axios.delete(
                            `/api/teacher/remove-experiment/${this.currentClassForExperiments.id}/${experimentId}`,
                            {
                                headers: { Authorization: `Bearer ${token}` }
                            }
                        );
                        this.classExperiments = this.classExperiments.filter(
                            exp => exp.id !== experimentId
                        );

                        // === 更新班级实验数量 ===
                        const classIndex = this.classes.findIndex(c => c.id === this.currentClassForExperiments.id);
                        if (classIndex !== -1) {
                            this.classes[classIndex].experimentCount--;
                        }
                        alert('实验已移除');
                    } catch (error) {
                        console.error('移除实验失败:', error);
                        alert('移除实验失败');
                    }
                },

                // 加载实验成绩数据
                async loadExperimentGrades() {
                    if (!this.selectedClass || !this.selectedExperiment) return;

                    this.loadingGrades = true;
                    try {
                        const token = this.getAuthToken();
                        const response = await axios.get(
                            `/api/teacher/grading/${this.selectedClass}/${this.selectedExperiment}`,
                            { headers: { Authorization: `Bearer ${token}` } }
                        );

                        this.criteriaList = response.data.criteria;
                        this.gradingData = response.data.gradingData;
                    } catch (error) {
                        console.error('加载成绩数据失败:', error);
                    } finally {
                        this.loadingGrades = false;
                    }
                },
                // 计算学生总分
                calculateTotalScore(student) {
                    return this.criteriaList.reduce((total, criteria) => {
                        const score = parseFloat(student.grades[criteria.id]) || 0;
                        return total + (score * criteria.proportion / 100);
                    }, 0).toFixed(1);
                },

                // 保存学生成绩
                async saveStudentGrades(student) {
                    try {
                        const token = this.getAuthToken();

                        // 为每个评分标准提交更新
                        const requests = this.criteriaList.map(criteria => {
                            const score = student.grades[criteria.id];
                            return axios.post('/api/teacher/grading', {
                                studentId: student.id,
                                experimentId: this.selectedExperiment,
                                criteriaId: criteria.id,
                                score: score !== null ? parseFloat(score) : null
                            }, { headers: { Authorization: `Bearer ${token}` } });
                        });

                        await Promise.all(requests);
                        alert('成绩保存成功！');
                    } catch (error) {
                        console.error('保存成绩失败:', error);
                        alert('保存成绩失败');
                    }
                },

                // 批改报告
                gradeReport(report) {
                    alert(`批改报告: ${report.studentName} - ${report.experimentName}`);
                },

                // 导出成绩
                exportGrades() {
                    this.loading = true;

                    // 使用axios模拟API请求
                    axios.get('/api/grades/export', {
                        params: {
                            classId: this.selectedClass
                        },
                        responseType: 'blob' // 用于文件下载
                    })
                        .then(response => {
                            // 创建下载链接
                            const url = window.URL.createObjectURL(new Blob([response.data]));
                            const link = document.createElement('a');
                            link.href = url;
                            link.setAttribute('download', `成绩单_${this.selectedClassText}.xlsx`);
                            document.body.appendChild(link);
                            link.click();

                            alert('成绩导出成功');
                        })
                        .catch(error => {
                            console.error('导出成绩失败:', error);
                            alert('导出成绩失败，请重试');
                        })
                        .finally(() => {
                            this.loading = false;
                        });
                },

                // 刷新待批改报告列表
                refreshPendingReports() {
                    this.loadClassExperiments();
                },

                // 查看学生详情
                viewStudentDetails(student) {
                    alert(`查看学生详情: ${student.name}`);
                },

                // 加载实验列表
                async loadExperiments() {
                    this.loadingExperiments = true;
                    try {
                        token = this.getAuthToken();
                    } catch (error) {
                        window.location.href = '/login.html';
                        return;
                    }

                    try {
                        // 添加认证头
                        const response = await axios.get('/api/teacher/experiments', {
                            headers: { Authorization: `Bearer ${token}` }
                        });

                        // 处理API响应
                        if (response.data && response.data.success) {
                            // 成功响应，包含data数组
                            this.experiments = response.data.data;
                        } else if (Array.isArray(response.data)) {
                            // 直接返回数组
                            this.experiments = response.data;
                        } else {
                            this.experiments = [];
                            throw new Error('无效的实验数据格式');
                        }

                    } catch (error) {
                        this.experiments = [];
                        console.error('加载实验失败:', error);
                        const errorMsg = error.response?.data?.message || error.message;
                        alert(`加载实验失败: ${errorMsg}`);
                    } finally {
                        this.loadingExperiments = false;
                    }
                },

                // 查看实验详情
                async viewExperimentDetails(experiment) {
                    this.currentExperiment = experiment;
                    this.showExperimentModal = true;
                },

                // 打开创建实验模态框
                openCreateExperimentModal() {
                    this.isEditingExperiment = false;
                    this.editExperimentData = {
                        title: '',
                        short_description: '',
                        full_description: '',
                        course_category: 'cs',
                        duration: 1,
                        image_url: '',
                        objectives: [{ objective: '' }],
                        resources: [{
                            name: '',
                            type: 'pdf',
                            file_path: '',
                            is_public: false
                        }]
                    };
                    this.showEditExperimentModal = true;
                },

                // 编辑实验
                editExperiment(experiment) {
                    this.isEditingExperiment = true;
                    this.currentExperiment = { ...experiment };

                    // 深拷贝实验数据用于编辑
                    this.editExperimentData = {
                        ...experiment,
                        objectives: experiment.objectives.map(obj => ({ ...obj })),
                        resources: experiment.resources.map(res => ({
                            ...res,
                            // 确保布尔值类型正确
                            is_public: res.is_public === 1 || res.is_public === true
                        }))
                    };

                    this.showExperimentModal = false;
                    this.showEditExperimentModal = true;
                },

                // 添加实验目标
                addObjective() {
                    this.editExperimentData.objectives.push({ objective: '' });
                },

                // 移除实验目标
                removeObjective(index) {
                    if (this.editExperimentData.objectives.length > 1) {
                        this.editExperimentData.objectives.splice(index, 1);
                    }
                },

                // 添加实验资源
                addResource() {
                    this.editExperimentData.resources.push({
                        name: '',
                        type: 'pdf',
                        file_path: '',
                        is_public: false
                    });
                },

                // 移除实验资源
                removeResource(index) {
                    if (this.editExperimentData.resources.length > 1) {
                        this.editExperimentData.resources.splice(index, 1);
                    }
                },

                // 触发封面图片上传
                triggerCoverUpload() {
                    this.$refs.coverUpload.click();
                },

                // 处理封面图片上传
                handleCoverUpload(event) {
                    const file = event.target.files[0];
                    if (!file) return;

                    // 检查文件类型
                    if (!file.type.match('image.*')) {
                        alert('请上传图片文件 (JPEG, PNG等)');
                        return;
                    }

                    // 检查文件大小 (最大5MB)
                    if (file.size > 5 * 1024 * 1024) {
                        alert('图片大小不能超过5MB');
                        return;
                    }

                    // 创建预览URL
                    const reader = new FileReader();
                    reader.onload = (e) => {
                        this.editExperimentData.image_url = e.target.result;
                    };
                    reader.readAsDataURL(file);
                },

                // 触发资源文件上传
                triggerResourceUpload(index) {
                    this.$refs[`resourceUpload${index}`][0].click();
                },

                // 处理资源文件上传
                handleResourceUpload(event, index) {
                    const file = event.target.files[0];
                    if (!file) return;

                    // 添加到资源对象
                    this.editExperimentData.resources[index].file = file;

                    // 自动设置资源名称（如果未设置）
                    if (!this.editExperimentData.resources[index].name) {
                        this.editExperimentData.resources[index].name = file.name;
                    }

                    // 自动检测文件类型（如果未设置）
                    if (!this.editExperimentData.resources[index].type) {
                        const ext = file.name.split('.').pop().toLowerCase();
                        const typeMap = {
                            'pdf': 'pdf',
                            'doc': 'docx', 'docx': 'docx',
                            'zip': 'code', 'rar': 'code', '7z': 'code',
                            'mp4': 'video', 'mov': 'video', 'avi': 'video',
                            'jpg': 'image', 'jpeg': 'image', 'png': 'image', 'gif': 'image'
                        };
                        this.editExperimentData.resources[index].type = typeMap[ext] || 'other';
                    }
                },

                // 格式化文件大小
                formatFileSize(bytes) {
                    if (bytes === 0) return '0 Bytes';
                    const k = 1024;
                    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
                    const i = Math.floor(Math.log(bytes) / Math.log(k));
                    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
                },

                // 保存实验（创建或更新）
                async saveExperiment() {
                    try {
                        alert('实验保存成功！');
                        this.closeEditExperimentModal();
                    } catch (error) {
                        console.error('保存实验失败:', error);
                        alert('保存实验失败');
                    }
                },

                // 删除实验
                async deleteExperiment(experiment) {
                    if (experiment.classCount > 0) {
                        alert('该实验已被班级关联，无法删除');
                        return;
                    }

                    if (!confirm(`确定要删除实验 "${experiment.title}" 吗？此操作不可恢复。`)) {
                        return;
                    }

                    alert('实验已删除');
                },

                // 关闭实验详情模态框
                closeExperimentModal() {
                    this.showExperimentModal = false;
                },

                // 关闭编辑实验模态框
                closeEditExperimentModal() {
                    this.showEditExperimentModal = false;
                },

                // 格式化日期
                formatDate(dateString) {
                    const options = { year: 'numeric', month: 'long', day: 'numeric' };
                    return new Date(dateString).toLocaleDateString('zh-CN', options);
                },

                // 获取资源图标
                getResourceIcon(type) {
                    const icons = {
                        pdf: 'fas fa-file-pdf',
                        docx: 'fas fa-file-word',
                        code: 'fas fa-code',
                        video: 'fas fa-video'
                    };
                    return icons[type] || 'fas fa-file';
                },


                // 新增方法 - 加载设置
                loadSettings() {
                    // 从本地存储加载设置
                    const savedSettings = localStorage.getItem('teacherSettings');
                    if (savedSettings) {
                        this.settings = JSON.parse(savedSettings);
                    }
                },

                // 新增方法 - 保存设置
                saveSettings() {
                    // 保存到本地存储
                    localStorage.setItem('teacherSettings', JSON.stringify(this.settings));
                    alert('设置已保存！');
                },

                // 设置活动菜单
                setActiveMenu(menuId) {
                    this.activeMenu = menuId;
                },

                // 切换下拉菜单
                toggleDropdown() {
                    this.isDropdownOpen = !this.isDropdownOpen;
                },

                // 编辑个人信息
                editProfile() {
                    alert('编辑个人信息功能');
                    this.closeDropdown();
                },
                // 修改密码
                changePassword() {
                    alert('修改密码功能');
                    this.closeDropdown();
                },

                // 关闭下拉菜单
                closeDropdown() {
                    this.isDropdownOpen = false;
                },

                // 退出登录
                logout() {
                    if (confirm('确定要退出系统吗？')) {
                        // 清除认证信息
                        localStorage.removeItem('authToken');
                        sessionStorage.removeItem('authToken');
                        // 重定向到登录页
                        window.location.href = '/index.html';
                    }
                }
            }
        });
    </script>
</body>

</html>